#include "CompresorDeTerminos.h"
#include "FrontCoding.h"

CompresorDeTerminos::CompresorDeTerminos(const std::string &path_salida_lexico, const std::string
		&path_salida_punteros) {
	this->path_lexico = path_salida_lexico;
	this->path_punteros = path_salida_punteros;
}

CompresorDeTerminos::~CompresorDeTerminos() {
}

void CompresorDeTerminos::comprimir(const std::string &path_entrada) {
	int longitud, nro_doc;
	FrontCoding f(4);
	FILE* input = fopen(path_entrada.c_str(), "r");
	this->lexico= fopen(this->path_lexico.c_str(),"w+");
	this->punteros = fopen(this->path_punteros.c_str(),"w+");


	fseek(input, 0L, SEEK_END );
	int final = ftell(input);
	fseek(input,0L, SEEK_SET);
	bool salida = false;
	char* buffer = new char[final];
	memset(buffer,0,final);
	int contador = 0;
	char* aux = buffer;
	fread(buffer,sizeof(char),final,input);
	while (!salida) {
		memcpy(&longitud,aux,4);
		aux = aux + 4;
		memcpy(&nro_doc,aux,4);
		aux = aux +4;
		char* termino = new char[longitud];
		memcpy(termino,aux,longitud);
		aux = aux + longitud;
		contador = contador + 4 +4 +longitud;
		Doc_frec* par[nro_doc];
		int i = 0;
		int doc_anterior = 0;
		while (i < nro_doc) {
			int doc, frec;
			memcpy(&doc, aux, 4);
			memcpy(&frec, aux, 4);
			par[i] = new Doc_frec();
			par[i]->doc = doc - doc_anterior;
			par[i]->frec = frec;
			doc = doc_anterior;
			i++;
		}
		aux = aux + (nro_doc * 2* 4 );
		contador = contador + (nro_doc*2*4);
		if (contador >= final) {
			salida = true;
		}
		this->tabla->agregar_entrada(this->pos_lexico, this->pos_punteros,nro_doc);
		this->comprimir_termino(&f, termino, longitud);
		this->comprimir_punteros(nro_doc, par);
		i = 0;
		while (i < nro_doc) {
			delete par[i];
			i++;
		}
		delete[] termino;
	}
	fclose(input);
	delete[] buffer;
}


void CompresorDeTerminos::comprimir_termino(FrontCoding* f,char* termino, int longitud) {
	int distintos, iguales;
	distintos = iguales = 0;
	f->comprimir_termino(termino, longitud, &iguales, &distintos);
	if (iguales == 0) {
		fwrite(termino,longitud,sizeof(char),this->punteros);
		this->pos_lexico = this->pos_lexico + longitud;
	}
	else {
		fwrite((termino+iguales), distintos, sizeof(char), this->punteros);
		this->pos_lexico = this->pos_lexico + distintos;
	}
	this->tabla->set_datos_frontcoding((longitud-iguales), iguales);
}
void CompresorDeTerminos::comprimir_punteros(int nro_doc, Doc_frec* par[]) {

}
